﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using ExtendedMvc.Tests.Model;
using ExtendedMvc.Tests.Model.Entities;
using ExtendedMvc.Tests.Model.Enumerations;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ExtendedMvc.Tests {


	/// <summary>
	///This is a test class for RadioButtonSetTest and is intended
	///to contain all RadioButtonSetTest Unit Tests
	///</summary>
	[TestClass()]
	public class RadioButtonSetTest {

		private static DummyDataSource database;
		private static ModelViewPage<Dummy> view;
		private static ModelViewForm<Dummy> form;

		/// <summary>
		///Gets or sets the test radio which provides
		///information about and functionality for the current test run.
		///</summary>
		public TestContext TestContext { get; set; }

		#region Additional test attributes
		// 
		//You can use the following additional attributes as you write your tests:
		//
		//Use ClassInitialize to run code before running the first test in the class
		[ClassInitialize()]
		public static void MyClassInitialize(TestContext testConradio) {
			database = new DummyDataSource();
			var dummy = database.Dummies.All().First();
			view = MvcMockHelpers.FakeViewPage("Index", dummy);
			form = new ModelViewForm<Dummy>(view.Html);
		}

		//Use ClassCleanup to run code after all tests in a class have run
		//[ClassCleanup()]
		//public static void MyClassCleanup() {
		//}
		//
		//Use TestInitialize to run code before running each test
		[TestInitialize()]
		public void MyTestInitialize() {
			view.ViewContext.ViewData.ModelState.Clear();
		}

		//Use TestCleanup to run code after each test has run
		//[TestCleanup()]
		//public void MyTestCleanup() {
		//}
		//
		#endregion

		/// <summary>
		///A test for CheckBoxList Constructor
		///</summary>
		[TestMethod()]
		[ExpectedException(typeof(System.ArgumentException))]
		public void RadioButtonSet_WithPropertyName_WithNoOption() {
			// Arrange
			var name = "BasicProperty";

			// Act
			var radioButtonSet = form.RadioButtonSet(name);
			var output = radioButtonSet.ToString();
		}

		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		public void RadioButtonSet_WithPropertyName_WithOptionArray() {
			// Arrange
			var name = "BasicProperty";
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var options = new object[] { expectedValue, "OtherValue" };
			var expectedOutput = string.Format(
@"<div id=""{0}_Options"" style=""display:inline-block;"" type=""optionList""><div>" +
@"<input checked=""checked"" id=""{0}_{1}"" name=""{0}"" type=""radio"" value=""{1}"" /><label for=""{0}_{1}"" id=""{0}_{1}_Label"">&nbsp;{1}</label>" +
@"<input id=""{0}_{2}"" name=""{0}"" type=""radio"" value=""{2}"" /><label for=""{0}_{2}"" id=""{0}_{2}_Label"">&nbsp;{2}</label>" +
@"</div></div>", name, options[0], options[1], expectedValue);

			// Act
			var radioButtonSet = form.RadioButtonSet(name).Options(options);
			var output = radioButtonSet.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		public void RadioButtonSet_WithPropertyName_WithSingleSelection() {
			// Arrange
			var name = "BasicProperty";
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var options = new object[] { expectedValue, "OtherValue" };
			var expectedOutput = string.Format(
@"<div id=""{0}_Options"" style=""display:inline-block;"" type=""optionList""><div>" +
@"<input id=""{0}_{1}"" name=""{0}"" type=""radio"" value=""{1}"" /><label for=""{0}_{1}"" id=""{0}_{1}_Label"">&nbsp;{1}</label>" +
@"<input checked=""checked"" id=""{0}_{2}"" name=""{0}"" type=""radio"" value=""{2}"" /><label for=""{0}_{2}"" id=""{0}_{2}_Label"">&nbsp;{2}</label>" +
@"</div></div>", name, options[0], options[1], expectedValue);

			// Act
			var radioButtonSet = form.RadioButtonSet(name).Options(options).Select("OtherValue");
			var output = radioButtonSet.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		[ExpectedException(typeof(ArgumentException))]
		public void RadioButtonSet_WithPropertyName_WithBlockMultiSelect() {
			// Arrange
			var name = "BasicProperty";
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var options = new object[] { expectedValue, "OtherValue" };

			// Act
			var radioButtonSet = form.RadioButtonSet(name).Options(options).Select(new List<object>() { "OtherValue" });
		}

		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		public void RadioButtonSet_ForModel_WithOptionArray() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var options = new object[] { expectedValue, "OtherValue" };
			var expectedOutput = string.Format(
@"<div id=""{0}_Options"" style=""display:inline-block;"" type=""optionList""><div>" +
@"<input checked=""checked"" id=""{0}_{1}"" name=""{0}"" type=""radio"" value=""{1}"" /><label for=""{0}_{1}"" id=""{0}_{1}_Label"">&nbsp;{1}</label>" +
@"<input id=""{0}_{2}"" name=""{0}"" type=""radio"" value=""{2}"" /><label for=""{0}_{2}"" id=""{0}_{2}_Label"">&nbsp;{2}</label>" +
@"</div></div>", expectedName, options[0], options[1]);

			// Act
			var radioButtonSet = form.RadioButtonSet(expectedName).Options(options);
			var output = radioButtonSet.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		public void RadioButtonSet_ForModel_WithMultiSelectList() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var options = new SelectListItem[] { new SelectListItem() { Value = expectedValue, Text = "Text1" }, new SelectListItem() { Value = "OtherValue", Text = "OtherValue" } };
			var multiSelectList = new MultiSelectList(options, "Value", "Text");
			var expectedOutput = string.Format(
@"<div id=""{0}_Options"" style=""display:inline-block;"" type=""optionList""><div>" +
@"<input checked=""checked"" id=""{0}_{1}"" name=""{0}"" type=""radio"" value=""{1}"" /><label for=""{0}_{1}"" id=""{0}_{1}_Label"">&nbsp;{3}</label>" +
@"<input id=""{0}_{2}"" name=""{0}"" type=""radio"" value=""{2}"" /><label for=""{0}_{2}"" id=""{0}_{2}_Label"">&nbsp;{4}</label>" +
@"</div></div>", expectedName, options[0].Value, options[1].Value, options[0].Text, options[1].Text);

			// Act
			var radioButtonSet = form.RadioButtonSet(expectedName).Options(multiSelectList);
			var output = radioButtonSet.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		public void RadioButtonSet_ForModel_WithIEnumerableItem() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var options = new List<string> { expectedValue, "OtherValue" };
			var expectedOutput = string.Format(
@"<div id=""{0}_Options"" style=""display:inline-block;"" type=""optionList""><div>" +
@"<input checked=""checked"" id=""{0}_{1}"" name=""{0}"" type=""radio"" value=""{1}"" /><label for=""{0}_{1}"" id=""{0}_{1}_Label"">&nbsp;{3}</label>" +
@"<input id=""{0}_{2}"" name=""{0}"" type=""radio"" value=""{2}"" /><label for=""{0}_{2}"" id=""{0}_{2}_Label"">&nbsp;{4}</label>" +
@"</div></div>", expectedName, options[0], options[1], options[0], options[1]);

			// Act
			var radioButtonSet = form.RadioButtonSet(expectedName).Options(options);
			var output = radioButtonSet.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		public void RadioButtonSet_ForModel_WithIDictionary() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var options = new Dictionary<object, string>();
			options.Add((object)expectedValue, "Text1");
			options.Add((object)"OtherValue", "Text2");
			var expectedOutput = string.Format(
@"<div id=""{0}_Options"" style=""display:inline-block;"" type=""optionList""><div>" +
@"<input checked=""checked"" id=""{0}_{1}"" name=""{0}"" type=""radio"" value=""{1}"" /><label for=""{0}_{1}"" id=""{0}_{1}_Label"">&nbsp;{3}</label>" +
@"<input id=""{0}_{2}"" name=""{0}"" type=""radio"" value=""{2}"" /><label for=""{0}_{2}"" id=""{0}_{2}_Label"">&nbsp;{4}</label>" +
@"</div></div>", expectedName, expectedValue, "OtherValue", options[expectedValue], options["OtherValue"]);

			// Act
			var radioButtonSet = form.RadioButtonSet(expectedName).Options(options);
			var output = radioButtonSet.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		public void RadioButtonSet_ForModel_WithAnonimousEnumerable() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var options = new object[] { new { Value = expectedValue, Text = "Text1" }, new { Value = "OtherValue", Text = "Text2" } };
			var expectedOutput = string.Format(
@"<div id=""{0}_Options"" style=""display:inline-block;"" type=""optionList""><div>" +
@"<input checked=""checked"" id=""{0}_{1}"" name=""{0}"" type=""radio"" value=""{1}"" /><label for=""{0}_{1}"" id=""{0}_{1}_Label"">&nbsp;{3}</label>" +
@"<input id=""{0}_{2}"" name=""{0}"" type=""radio"" value=""{2}"" /><label for=""{0}_{2}"" id=""{0}_{2}_Label"">&nbsp;{4}</label>" +
@"</div></div>", expectedName, expectedValue, "OtherValue", "Text1", "Text2");

			// Act
			var radioButtonSet = form.RadioButtonSet(expectedName).Options(options, "Value", "Text");
			var output = radioButtonSet.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		public void RadioButtonSet_ForModel_WithEnum() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.EnumProperty;
			var expectedName = "EnumProperty";
			var expectedOutput = string.Format(
@"<div id=""{0}_Options"" style=""display:inline-block;"" type=""optionList""><div>" +
@"<input checked=""checked"" id=""{0}_{1}"" name=""{0}"" type=""radio"" value=""{1}"" /><label for=""{0}_{1}"" id=""{0}_{1}_Label"">&nbsp;{3}</label>" +
@"<input id=""{0}_{2}"" name=""{0}"" type=""radio"" value=""{2}"" /><label for=""{0}_{2}"" id=""{0}_{2}_Label"">&nbsp;{4}</label>" +
@"</div></div>", expectedName, DummyEnum.FirstValue.ToString(), DummyEnum.SecondValue.ToString(), DummyEnum.FirstValue.ToString(), DummyEnum.SecondValue.ToString());

			// Act
			var radioButtonSet = form.RadioButtonSet(expectedName).Options<DummyEnum>();
			var output = radioButtonSet.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		public void RadioButtonSet_ForRequiredProperty() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.RequiredProperty;
			var expectedName = "RequiredProperty";
			var options = new object[] { expectedValue, "OtherValue" };
			var expectedOutput = string.Format(
@"<div id=""{0}_Options"" required=""required"" style=""display:inline-block;"" type=""optionList""><div>" +
@"<input checked=""checked"" id=""{0}_{1}"" name=""{0}"" required=""required"" type=""radio"" value=""{1}"" /><label for=""{0}_{1}"" id=""{0}_{1}_Label"" required=""required"">&nbsp;{1}</label>" +
@"<input id=""{0}_{2}"" name=""{0}"" required=""required"" type=""radio"" value=""{2}"" /><label for=""{0}_{2}"" id=""{0}_{2}_Label"" required=""required"">&nbsp;{2}</label>" +
@"</div></div>", expectedName, options[0], options[1]);

			// Act
			var radioButtonSet = form.RadioButtonSet(expectedName).Options(options);
			var output = radioButtonSet.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		public void RadioButtonSet_ForRequiredField_WithValidationMessage() {
			// Arrange
			var expectedErrorMessage = "Field is required.";
			view.ViewContext.ViewData.ModelState.AddModelError("RequiredProperty", expectedErrorMessage);
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.RequiredProperty;
			var expectedName = "RequiredProperty";
			var options = new object[] { expectedValue, "OtherValue" };
			var expectedOutput = string.Format(
@"<div class=""input-validation-error"" id=""{0}_Options"" required=""required"" style=""display:inline-block;"" type=""optionList""><div>" +
@"<input checked=""checked"" class=""input-validation-error"" id=""{0}_{1}"" name=""{0}"" required=""required"" type=""radio"" value=""{1}"" /><label class=""input-validation-error"" for=""{0}_{1}"" id=""{0}_{1}_Label"" required=""required"">&nbsp;{1}</label>" +
@"<input class=""input-validation-error"" id=""{0}_{2}"" name=""{0}"" required=""required"" type=""radio"" value=""{2}"" /><label class=""input-validation-error"" for=""{0}_{2}"" id=""{0}_{2}_Label"" required=""required"">&nbsp;{2}</label>" +
@"</div></div>" +
@"<span class=""field-validation-error"" id=""{0}_Error"">{3}</span>"
, expectedName, options[0], options[1], expectedErrorMessage);

			// Act
			var radioButtonSet = form.RadioButtonSet(expectedName).Options(options).AddValidationMessage();
			var output = radioButtonSet.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		public void RadioButtonSet_WithDirectionVertical() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var options = new object[] { expectedValue, "OtherValue1" };
			var expectedOutput = string.Format(
@"<div id=""{0}_Options"" style=""display:inline-block;"" type=""optionList"">" +
@"<div><input checked=""checked"" id=""{0}_{1}"" name=""{0}"" type=""radio"" value=""{1}"" /><label for=""{0}_{1}"" id=""{0}_{1}_Label"">&nbsp;{1}</label></div>" +
@"<div><input id=""{0}_{2}"" name=""{0}"" type=""radio"" value=""{2}"" /><label for=""{0}_{2}"" id=""{0}_{2}_Label"">&nbsp;{2}</label></div>" +
@"</div>", expectedName, options[0], options[1]);

			// Act
			var radioButtonSet = form.RadioButtonSet(expectedName).Options(options).Direction(Html.ListDirection.Vertically);
			var output = radioButtonSet.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		public void RadioButtonSet_WithColumnsHorizontaly() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var options = new object[] { expectedValue, "OtherValue1", "OtherValue2", "OtherValue3", "OtherValue4", "OtherValue5" };
			var expectedOutput = string.Format(
@"<div id=""{0}_Options"" style=""display:inline-block;"" type=""optionList"">" +
@"<div><input checked=""checked"" id=""{0}_{1}"" name=""{0}"" type=""radio"" value=""{1}"" /><label for=""{0}_{1}"" id=""{0}_{1}_Label"">&nbsp;{1}</label><input id=""{0}_{2}"" name=""{0}"" type=""radio"" value=""{2}"" /><label for=""{0}_{2}"" id=""{0}_{2}_Label"">&nbsp;{2}</label></div>" +
@"<div><input id=""{0}_{3}"" name=""{0}"" type=""radio"" value=""{3}"" /><label for=""{0}_{3}"" id=""{0}_{3}_Label"">&nbsp;{3}</label><input id=""{0}_{4}"" name=""{0}"" type=""radio"" value=""{4}"" /><label for=""{0}_{4}"" id=""{0}_{4}_Label"">&nbsp;{4}</label></div>" +
@"<div><input id=""{0}_{5}"" name=""{0}"" type=""radio"" value=""{5}"" /><label for=""{0}_{5}"" id=""{0}_{5}_Label"">&nbsp;{5}</label><input id=""{0}_{6}"" name=""{0}"" type=""radio"" value=""{6}"" /><label for=""{0}_{6}"" id=""{0}_{6}_Label"">&nbsp;{6}</label></div>" +
@"</div>", expectedName, options[0], options[1], options[2], options[3], options[4], options[5]);

			// Act
			var radioButtonSet = form.RadioButtonSet(expectedName).Options(options).Columns(2);
			var output = radioButtonSet.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}


		/// <summary>
		///A test for RadioButtonSet Constructor
		///</summary>
		[TestMethod()]
		public void RadioButtonSet_WithColumnsVerticaly() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedValue = dummy.BasicProperty;
			var expectedName = "BasicProperty";
			var options = new object[] { expectedValue, "OtherValue1", "OtherValue2", "OtherValue3", "OtherValue4", "OtherValue5" };
			var expectedOutput = string.Format(
@"<div id=""{0}_Options"" style=""display:inline-block;"" type=""optionList"">" +
@"<div><input checked=""checked"" id=""{0}_{1}"" name=""{0}"" type=""radio"" value=""{1}"" /><label for=""{0}_{1}"" id=""{0}_{1}_Label"">&nbsp;{1}</label><input id=""{0}_{2}"" name=""{0}"" type=""radio"" value=""{2}"" /><label for=""{0}_{2}"" id=""{0}_{2}_Label"">&nbsp;{2}</label></div>" +
@"<div><input id=""{0}_{3}"" name=""{0}"" type=""radio"" value=""{3}"" /><label for=""{0}_{3}"" id=""{0}_{3}_Label"">&nbsp;{3}</label><input id=""{0}_{4}"" name=""{0}"" type=""radio"" value=""{4}"" /><label for=""{0}_{4}"" id=""{0}_{4}_Label"">&nbsp;{4}</label></div>" +
@"<div><input id=""{0}_{5}"" name=""{0}"" type=""radio"" value=""{5}"" /><label for=""{0}_{5}"" id=""{0}_{5}_Label"">&nbsp;{5}</label><input id=""{0}_{6}"" name=""{0}"" type=""radio"" value=""{6}"" /><label for=""{0}_{6}"" id=""{0}_{6}_Label"">&nbsp;{6}</label></div>" +
@"</div>", expectedName, options[0], options[3], options[1], options[4], options[2], options[5]);

			// Act
			var radioButtonSet = form.RadioButtonSet(expectedName).Options(options).Columns(2).Direction(Html.ListDirection.Vertically);
			var output = radioButtonSet.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}
	}
}
